<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

class Dispatcher{
var $base = false;
var $here = false;
var $params = null;

function __construct($url = null, $base = false) {
    if ($url !== null) {
        return $this->dispatch($url);
    }
}    

function dispatch($url = null, $additionalParams = array()) {    
    if ($this->base === false){
        $replace = array('<', '>', '*', '\'', '"');
        $this->base = str_replace($replace, '', dirname(env('PHP_SELF')));
    }

    /*
    if ($url){
        $_GET['url'] = $url;
    }
    $url = $this->getUrl();
     * 
     */
    //echo $url;
    $url = $this->getUrl();
    $this->params = array_merge($this->parseParams($url), $additionalParams);        

     
    //$this->base;
    $this->here = $this->base;
    $controller =& $this->__getController();
    if (!is_object($controller)){
        echo "Não existe o controle {$this->params['controle']}";
        return;
    }
    $controller->base = $this->base;
    $controller->here = $this->here;
    //$controller->webroot = $this->webroot;
    //$controller->plugin = isset($this->params['plugin']) ? $this->params['plugin'] : null;
    $controller->params =& $this->params;
    $controller->action =& $this->params['action'];
    $controller->passedArgs = array_merge($this->params['pass'], $this->params['named']);
    if (!empty($this->params['data'])) {
        $controller->data =& $this->params['data'];
    } else {
        $controller->data = null;
    }        

    return $this->_invoke($controller, $this->params);

}
    
function &__getController(){
    $controller = false;
    //print_r($this->params);
    $ctrlClass = (is_null($this->params['controle'])? CONTROLE_DEFAULT : $this->params['controle']);
    $ctrlClass .= 'controle';
    if (file_exists("app.control".DS."{$ctrlClass}.php")){
        include "{$ctrlClass}.php";
    }
    if (class_exists($ctrlClass)) {
        $controller =& new $ctrlClass();
    }
    return $controller;
}
    
function _invoke(&$controller, $params){
    
    //print_r($controller->methods);
    //print_r($params);
		$methods = array_flip($controller->methods);
        
		if (!isset($methods[strtolower($params['action'])])) {
            echo "Método {$params['action']} não encontrado";
			return "Error action not found";
		}

    

       // echo env('SCRIPT_NAME').'<br/>';
       //print_r($controller);
		$output = call_user_func_array(array(&$controller, $params['action']), $params['pass']);

		if ($controller->autoRender) {
            $controller->output = $controller->render();
		} elseif (empty($controller->output)) {
			$controller->output = $output;
		}
		//$controller->shutdownProcess();
/*
		if (isset($params['return'])) {
			return $controller->output;
		}
 * 
 */
		echo $controller->output;

}
    
    
function parseParams($fromUrl) {
    $params = array();

    if (isset($_POST)) {
        $params['form'] = $_POST;
        if (ini_get('magic_quotes_gpc') === '1') {
            $params['form'] = stripslashes_deep($params['form']);
        }
        if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
            $params['form']['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
        }
        if (isset($params['form']['_method'])) {
            if (!empty($_SERVER)) {
                $_SERVER['REQUEST_METHOD'] = $params['form']['_method'];
            } else {
                $_ENV['REQUEST_METHOD'] = $params['form']['_method'];
            }
            unset($params['form']['_method']);
        }
    }
    //$namedExpressions = Router::getNamedExpressions();
    //extract($namedExpressions);
    //include CONFIGS . 'routes.php';
    $params = array_merge($this->parse($fromUrl), $params);
    
    if (strlen($params['action']) === 0 || is_numeric($params['action'])) {
        $params['action'] = 'index';
    }
    if (isset($params['form']['data'])) {
        $params['data'] = $params['form']['data'];
        unset($params['form']['data']);
    }
    if (isset($_GET)) {
        if (ini_get('magic_quotes_gpc') === '1') {
            $url = stripslashes_deep($_GET);
        } else {
            $url = $_GET;
        }
        if (isset($params['url'])) {
            $params['url'] = array_merge($params['url'], $url);
        } else {
            $params['url'] = $url;
        }
    }

    foreach ($_FILES as $name => $data) {
        if ($name != 'data') {
            $params['form'][$name] = $data;
        }
    }

    if (isset($_FILES['data'])) {
        foreach ($_FILES['data'] as $key => $data) {
            foreach ($data as $model => $fields) {
                if (is_array($fields)) {
                    foreach ($fields as $field => $value) {
                        if (is_array($value)) {
                            foreach ($value as $k => $v) {
                                $params['data'][$model][$field][$k][$key] = $v;
                            }
                        } else {
                            $params['data'][$model][$field][$key] = $value;
                        }
                    }
                } else {
                    $params['data'][$model][$key] = $fields;
                }
            }
        }
    }
    return $params;
}    
    
function parse($url){
    $out = array(
    'pass' => array(),
    'named' => array(),
    );
    $r = $ext = null;

    if (ini_get('magic_quotes_gpc') === '1') {
        $url = stripslashes_deep($url);
    }

    if ($url && strpos($url, '/') !== 0) {
        $url = '/' . $url;
    }
    if (strpos($url, '?') !== false) {
        $url = substr($url, 0, strpos($url, '?'));
    }
    
    $url = str_replace(env('SCRIPT_NAME'), "", $url);
    $controleAction = explode('/', $url);
    $params = array('controle' => null, 'action' => null);
    $params['action'] = (isset($controleAction[2]) ? $controleAction[2] : null );
    $params['controle'] = (isset($controleAction[1]) ? $controleAction[1] : null );
    for ($index = 3; $index < count($controleAction); $index++) {
        if(strlen($controleAction[$index]) > 0){
            array_push($out['pass'], $controleAction[$index]);
        }
    }
    $out = array_merge($params, $out);
    
    
    if (!empty($ext) && !isset($out['url']['ext'])) {
				$out['url']['ext'] = $ext;
	}
	return $out;    
}

	/**
	 * Returns and sets the $_GET[url] derived from the REQUEST_URI
	 *
	 * @param string $uri Request URI
	 * @param string $base Base path
	 * @return string URL
	 * @access public
	 */
	function getUrl($uri = null, $base = null) {
		if (empty($_GET['url'])) {
			if ($uri == null) {
				$uri = $this->uri();
			}
			if ($base == null) {
				$base = $this->base;
			}
			$url = null;
			$tmpUri = preg_replace('/^(?:\?)?(?:\/)?/', '', $uri);
			$baseDir = preg_replace('/^\//', '', dirname($base)) . '/';

			if ($tmpUri === '/' || $tmpUri == $baseDir || $tmpUri == $base) {
				$url = $_GET['url'] = '/';
			} else {
				if ($base && strpos($uri, $base) !== false) {
					$elements = explode($base, $uri);
				} elseif (preg_match('/^[\/\?\/|\/\?|\?\/]/', $uri)) {
					$elements = array(1 => preg_replace('/^[\/\?\/|\/\?|\?\/]/', '', $uri));
				} else {
					$elements = array();
				}

				if (!empty($elements[1])) {
					$_GET['url'] = $elements[1];
					$url = $elements[1];
				} else {
					$url = $_GET['url'] = '/';
				}

				if (strpos($url, '/') === 0 && $url != '/') {
					$url = $_GET['url'] = substr($url, 1);
				}
			}
		} else {
			$url = $_GET['url'];
		}
		if ($url{0} == '/') {
			$url = substr($url, 1);
		}
		return $url;
	}

	/**
	 * Returns the REQUEST_URI from the server environment, or, failing that,
	 * constructs a new one, using the PHP_SELF constant and other variables.
	 *
	 * @return string URI
	 * @access public
	 */
	function uri() {
		foreach (array('HTTP_X_REWRITE_URL', 'REQUEST_URI', 'argv') as $var) {
			if ($uri = env($var)) {
				if ($var == 'argv') {
					$uri = $uri[0];
				}
				break;
			}
		}
        $base = null;
		//$base = preg_replace('/^\//', '', '' . Configure::read('App.baseUrl'));
       
		if ($base) {
			$uri = preg_replace('/^(?:\/)?(?:' . preg_quote($base, '/') . ')?(?:url=)?/', '', $uri);
		}
		if (PHP_SAPI == 'isapi') {
			$uri = preg_replace('/^(?:\/)?(?:\/)?(?:\?)?(?:url=)?/', '', $uri);
		}
		if (!empty($uri)) {
			if (key($_GET) && strpos(key($_GET), '?') !== false) {
				unset($_GET[key($_GET)]);
			}
			$uri = explode('?', $uri, 2);

			if (isset($uri[1])) {
				parse_str($uri[1], $_GET);
			}
			$uri = $uri[0];
		} else {
			$uri = env('QUERY_STRING');
		}
		if (is_string($uri) && strpos($uri, 'index.php') !== false) {
			list(, $uri) = explode('index.php', $uri, 2);
		}
		if (empty($uri) || $uri == '/' || $uri == '//') {
			return '';
		}
		return str_replace('//', '/', '/' . $uri);
	}    
    
} 

?>
